#include "junix.h"
using namespace std;

class A
{
	public:
		A() : content(0) { 
		}

		A(const A& other)
			:content(other.content?other.content->clone():0) {
		}

		template <typename ValueType>
		A(const ValueType & value)
		:content(new holder<ValueType>(value)) {
		}

		~A() {
			delete content;
		}

		A& swap(A & rhs) {
			std::swap(content, rhs.content);
			return *this;
		}

		A& operator= (const A& rhs) {
			A(rhs).swap(*this);
			return *this;
		}

		template <typename ValueType>
		A& operator= (const ValueType & value) {
			A(value).swap(*this);
			return *this;
		} 

		bool empty() {
			return !content;
		}

		const std::type_info & type() const {
			return content? content->type() : typeid(void);
		}



















//===============================================================
		class placeholder {
			public:
				placeholder() { }
				virtual ~placeholder() { }
				virtual const std::type_info & type() const = 0; 
				virtual placeholder* clone() const = 0;
		};

		template <typename ValueType>
			class holder:public placeholder {
				public:
					holder(const ValueType & value)
						:held(value) {
					}

					const  std::type_info & type() const {
						return typeid(ValueType);
					}

					placeholder* clone() const {
						return new holder(held);
					}

				public:
					ValueType held;
				private:
					holder & operator= (const holder & );
			};

//===============================================================



	public:
		placeholder * content;
};

int main(int argc, char **argv)
{
	A a;
	int i = 9 ;
	a = i;
	a = string("hello");

	A b(9999);
}
